/*
 * Cache.java
 *
 * Created on 29 de Agosto de 2010, 17:34
 *
 */

package intopo.evogame.partnerselection;

import intopo.game.Strategy;
import intopo.game.Game;

import cern.jet.random.engine.MersenneTwister;
import cern.jet.random.Normal;

/**
 * This class contains data that is used often in instances of classes
 * {@code Player} and {@code Populaation}.  Since this data is constant,
 * instead of passsing it to the methods, it is located in this class.
 *
 * @author <a href="mailto:plsm@ua.pt">Pedro Lopes da Silva Mariano</a>
 *
 * @version 1.0 29 de Agosto de 2010
 */
public class Cache {
	/**
	 * Lowest payoff obtained in the game.
	 */
	static public float minPayoff;
	
	/**
	 * Highest payoff obtained in the game.
	 */
	static public float maxPayoff;

	static short paretoWeight;
	
	static float payoffRange;
	
	/**
	 * Standard deviation of the Normal distribution used to mutate the
	 * utility threshold gene of a player's chromosome.
	 */
	static public float payoffStandardDeviation;
	/**
	 * Number of players in the game.
	 */
	static public int numberPlayers = -1;
	
	/**
	 * Number of players in the game minus 1.
	 */
	static public int numberPartners = -1;
	
	static public MersenneTwister supply;
	/**
	 * Normal distribution.
	 */
	static public Normal normal;
	/**
	 * Array that contains sigmoid values.  These values are used to
	 * calculate the probability of a player to die based on carrying capacity and/or expected longevity. The index to this array
	 * is a function of player's age and number of players.
	 */
	static public int[] sigmoid1;
	/**
	 * Array that contains sigmoid values.  These values are used to
	 * calculate the probability of a player to die based on carrying capacity and/or expected longevity. The index to this array
	 * is a function of player's age and number of players.
	 */
	static public int[] sigmoid2;
	
//	/**
//	 * Array that contains minimum number of neighbours per pool size.  The
//	 * length of the combination vector has an upper bound.  This bound is
//	 * related to the number of available partners and the number of players in
//	 * the game.  The number of cannot be higher than the number of ways of
//	 * picking {@code n-1} partners out of {@code k} partners.
//	 */
//	static int minNeighbours[];

	/**
	 * Creates a new instance of Cache
	 */
	private Cache () {
		
	}
	
	static public <S extends Strategy<S>>
		void init (Game<S> game, MersenneTwister supply)
	{
		Cache.maxPayoff = game.highestPayoff ();
		Cache.minPayoff = game.lowestPayoff ();
		Cache.payoffRange = Cache.maxPayoff - Cache.minPayoff;
		Cache.paretoWeight = (short) ((game.paretoPayoff () - Cache.minPayoff) * Short.MAX_VALUE / Cache.payoffRange);
		Cache.payoffStandardDeviation = Cache.payoffRange / 2;
		Cache.numberPartners = game.numberPlayers () - 1;
		Cache.numberPlayers = game.numberPlayers ();
		Cache.supply = supply;
		Cache.normal = new Normal (1, 0, supply);
//		Cache.sigmoid1 = Util.logitFunction (PlainAgingPlayer.Parameters.carryingCapacity, 2 * PlainAgingPlayer.Parameters.carryingCapacity);
//		if (PlainAgingPlayer.Parameters.death == PlainAgingPlayer.Death.SEPARATED) {
//			Cache.sigmoid2 = Util.logitFunction (PlainAgingPlayer.Parameters.expectedLongevity, 20 + PlainAgingPlayer.Parameters.expectedLongevity);
//		}
//		else {
//			Cache.sigmoid2 = null;
//		}
	}
	
	public static void debug () {
		System.out.println ("Payoff domain: [" + Cache.minPayoff + " , " + Cache.maxPayoff + " ]");
		System.out.println ("Payoff range: " + Cache.payoffRange);
		System.out.println ("Standard deviation used to mutate utility threshold: " + Cache.payoffStandardDeviation);
		System.out.println ("Number players: " + Cache.numberPlayers + " number partners: " + Cache.numberPartners);
		System.out.println ("Sigmoid:");
		for (int v : Cache.sigmoid1) {
			System.out.format ("%15d", v);
		}
		System.out.println ();
//		System.out.println ("Minimum neighbours:");
//		for (int m : Cache.minNeighbours) {
//			System.out.print (" ");
//			System.out.print (m);
//		}
//		System.out.println ();
	}
}
